// API服务文件
const ConfigManager = require('../config/config-manager.js');
const ApiConfig = ConfigManager.getApiConfig();
const MessageUtil = require('./message-util.js');

class ApiService {
  constructor() {
    this.config = ApiConfig;
    this.userUniqueId = null;
    this.accessToken = null;
    this.userCode = null;
    this.userInfo = null;
    this.isLoggedIn = false;
    this.init();
  }

  // 初始化
  init() {
    this.ensureUserUniqueId();
    this.loadAuthInfo();
  }

  // 加载认证信息
  loadAuthInfo() {
    try {
      const authKeys = this.config.auth.storageKeys;
      this.accessToken = wx.getStorageSync(authKeys.accessToken);
      this.userCode = wx.getStorageSync(authKeys.userCode);
      this.userInfo = wx.getStorageSync(authKeys.userInfo);
      this.isLoggedIn = wx.getStorageSync(authKeys.isLoggedIn) || false;
    } catch (error) {
      console.error('加载认证信息失败:', error);
      this.clearAuthInfo();
    }
  }

  // 保存认证信息
  saveAuthInfo(authData) {
    try {
      const authKeys = this.config.auth.storageKeys;
      
      // 提取关键信息
      this.accessToken = authData.token;
      this.userCode = authData.user_code;
      this.userInfo = authData;
      this.isLoggedIn = true;

      // 验证必要信息是否存在
      if (!this.accessToken) {
        console.error('警告：token为空');
      }
      if (!this.userCode) {
        console.error('警告：user_code为空');
      }

      // 保存到本地存储
      wx.setStorageSync(authKeys.accessToken, this.accessToken);
      wx.setStorageSync(authKeys.userCode, this.userCode);
      wx.setStorageSync(authKeys.userInfo, this.userInfo);
      wx.setStorageSync(authKeys.isLoggedIn, true);
      
      console.log('认证信息保存成功');
      
    } catch (error) {
      console.error('保存认证信息失败:', error);
    }
  }

  // 清除认证信息
  clearAuthInfo() {
    try {
      const authKeys = this.config.auth.storageKeys;
      this.accessToken = null;
      this.userCode = null;
      this.userInfo = null;
      this.isLoggedIn = false;

      wx.removeStorageSync(authKeys.accessToken);
      wx.removeStorageSync(authKeys.userCode);
      wx.removeStorageSync(authKeys.userInfo);
      wx.removeStorageSync(authKeys.isLoggedIn);
    } catch (error) {
      console.error('清除认证信息失败:', error);
    }
  }

  // 检查登录状态
  isUserLoggedIn() {
    return this.isLoggedIn && this.accessToken && this.userCode;
  }

  // 静默登录
  async silentLogin() {
    try {
      // 获取微信授权码
      const loginResult = await new Promise((resolve, reject) => {
        wx.login({
          success: resolve,
          fail: reject
        });
      });

      if (!loginResult.code) {
        throw new Error('获取微信授权码失败');
      }

      // 调用登录接口
      const response = await this.wxLogin(loginResult.code);
      
      // 检查登录是否成功
      // 根据接口文档，成功时 result="true" 且 statusCode=3001
      // 注意：statusCode可能是字符串格式
      if (response.result === "true" && (response.statusCode === 3001 || response.statusCode === "3001")) {
        console.log('静默登录成功');
        
        // 登录成功，保存认证信息
        this.saveAuthInfo(response.data);
        
        return {
          success: true,
          userInfo: response.data
        };
              } else {
          // 登录失败
          console.error('登录失败:', response.message || '未知错误');
          throw new Error(response.message || '登录失败');
        }
    } catch (error) {
      console.error('静默登录失败:', error);
      this.clearAuthInfo();
      throw new Error('服务异常');
    }
  }

  // 微信登录接口
  async wxLogin(code) {
    return new Promise((resolve, reject) => {
      const url = this.config.server.baseUrl + this.config.endpoints.wxLogin;
      
      // 构建表单数据
      const requestData = {
        code: code,
        param_corpCode: this.config.auth.corpCode
      };
      
      wx.request({
        url: url,
        method: 'POST',
        data: requestData, // 使用表单数据格式
        timeout: this.config.server.timeout,
        header: {
          'Content-Type': 'application/x-www-form-urlencoded',
          'Accept': 'application/json'
        },
        success: (res) => {
          
          if (res.statusCode === 200) {
            resolve(res.data);
          } else {
            reject(new Error(`HTTP错误: ${res.statusCode}`));
          }
        },
        fail: (error) => {
          console.error('登录网络请求失败:', error);
          reject(new Error('网络请求失败'));
        }
      });
    });
  }

  // 确保用户唯一标识
  ensureUserUniqueId() {
    try {
      let userId = wx.getStorageSync(this.config.userIdentity.storageKey);
      if (!userId) {
        // 生成唯一标识：前缀 + 时间戳 + 随机数
        userId = this.config.userIdentity.prefix + 
                Date.now() + '_' + 
                Math.random().toString(36).substr(2, 9);
        wx.setStorageSync(this.config.userIdentity.storageKey, userId);
      }
      this.userUniqueId = userId;
    } catch (error) {
      console.error('获取用户唯一标识失败:', error);
      // 临时标识
      this.userUniqueId = this.config.userIdentity.prefix + 'temp_' + Date.now();
    }
  }

  // 检查频率限制
  checkRateLimit(isBatch = false) {
    const now = Date.now();
    const rateConfig = this.config.rateLimit;
    
    try {
      // 检查单个/批量生成间隔
      const intervalKey = isBatch ? 
        rateConfig.storageKeys.lastBatchGen : 
        rateConfig.storageKeys.lastSingleGen;
      const requiredInterval = isBatch ? 
        rateConfig.batchGenInterval : 
        rateConfig.singleGenInterval;
      
      const lastGenTime = wx.getStorageSync(intervalKey) || 0;
      const timeSinceLastGen = now - lastGenTime;
      
      if (timeSinceLastGen < requiredInterval) {
        const waitTime = Math.ceil((requiredInterval - timeSinceLastGen) / 1000);
        return {
          allowed: false,
          message: `请等待${waitTime}秒后再试`,
          waitTime: waitTime
        };
      }

      // 检查每分钟请求限制
      const history = this.getRequestHistory();
      const currentMinute = Math.floor(now / 60000);
      const currentMinuteRequests = history.filter(time => 
        Math.floor(time / 60000) === currentMinute
      ).length;
      
      if (currentMinuteRequests >= rateConfig.maxRequestsPerMinute) {
        return {
          allowed: false,
          message: '请求过于频繁，请稍后再试',
          waitTime: 60
        };
      }

      return { allowed: true };
    } catch (error) {
      console.error('频率检查失败:', error);
      return { allowed: true }; // 检查失败时允许请求
    }
  }

  // 获取请求历史
  getRequestHistory() {
    try {
      const history = wx.getStorageSync(this.config.rateLimit.storageKeys.requestHistory) || [];
      const now = Date.now();
      // 只保留最近一分钟的记录
      return history.filter(time => now - time < 60000);
    } catch (error) {
      console.error('获取请求历史失败:', error);
      return [];
    }
  }

  // 记录请求时间
  recordRequest(isBatch = false) {
    const now = Date.now();
    const rateConfig = this.config.rateLimit;
    
    try {
      // 记录单个/批量生成时间
      const intervalKey = isBatch ? 
        rateConfig.storageKeys.lastBatchGen : 
        rateConfig.storageKeys.lastSingleGen;
      wx.setStorageSync(intervalKey, now);

      // 记录到请求历史
      const history = this.getRequestHistory();
      history.push(now);
      wx.setStorageSync(rateConfig.storageKeys.requestHistory, history);
    } catch (error) {
      console.error('记录请求时间失败:', error);
    }
  }

  // 生成二维码/条形码
  async generateCode(params) {
    const {
      codeType,        // 码类型：'qrcode' | 'barcode'
      subType,         // 子类型：'standard' | 'micro' | 'Code 128' 等
      content,         // 内容（单个或数组）
      batchMode = false,  // 是否批量模式
      options = {}     // 其他选项（颜色、尺寸等）
    } = params;

    // 频率检查
    const rateCheck = this.checkRateLimit(batchMode);
    if (!rateCheck.allowed) {
      throw new Error(rateCheck.message);
    }

    // 验证参数
    this.validateParams(params);

    // 构建请求数据
    const requestData = this.buildRequestData(params);

    try {
      // 记录请求时间
      this.recordRequest(batchMode);

      // 发送请求
      const response = await this.sendRequest(requestData);
      return response;
    } catch (error) {
      console.error('生成请求失败:', error);
      throw error;
    }
  }

  // 验证参数
  validateParams(params) {
    const { codeType, subType, content, batchMode } = params;

    if (!codeType || !subType) {
      throw new Error('缺少必要的码类型参数');
    }

    if (!content || (Array.isArray(content) && content.length === 0)) {
      throw new Error('内容不能为空');
    }

    if (batchMode) {
      const contentArray = Array.isArray(content) ? content : [content];
      if (contentArray.length > this.config.rateLimit.maxBatchSize) {
        throw new Error(`批量生成最多支持${this.config.rateLimit.maxBatchSize}个`);
      }
    }
  }

  // 构建请求数据
  buildRequestData(params) {
    const { codeType, subType, content, batchMode, options = {} } = params;

    // 映射码类型
    let mappedType;
    if (codeType === 'qrcode') {
      mappedType = this.config.codeTypes.qrcode[subType];
    } else if (codeType === 'barcode') {
      mappedType = this.config.codeTypes.barcode[subType];
    }

    if (!mappedType) {
      throw new Error('不支持的码类型');
    }

    return {
      user_id: this.userUniqueId,
      code_type: mappedType,
      batch_mode: batchMode,
      content: batchMode ? (Array.isArray(content) ? content : [content]) : content,
      options: {
        foreground_color: options.foregroundColor || '#000000',
        background_color: options.backgroundColor || '#ffffff',
        size: options.size || 300,
        ...options
      }
    };
  }

  // 发送请求
  sendRequest(data) {
    return new Promise((resolve, reject) => {
      const url = this.config.server.baseUrl + this.config.endpoints.codeGeneration;
      
      // 构建请求头，包含认证信息
      const headers = {
        'content-type': 'application/json'
      };
      
      // 添加认证头（如果已登录）
      if (this.isUserLoggedIn()) {
        headers['S-Access-Token'] = this.accessToken;
        headers['S-Code'] = this.userCode;
      }
      
      wx.request({
        url: url,
        method: 'POST',
        data: data,
        timeout: this.config.server.timeout,
        responseType: data.batch_mode ? 'arraybuffer' : 'arraybuffer', // 都用arraybuffer接收二进制数据
        header: headers,
        success: (res) => {
          // 检查并更新令牌
          this.handleTokenRefresh(res);
          
          if (res.statusCode === 200) {
            resolve({
              success: true,
              data: res.data,
              isBatch: data.batch_mode
            });
          } else {
            reject(new Error(`服务器错误: ${res.statusCode}`));
          }
        },
        fail: (error) => {
          console.error('请求失败:', error);
          reject(new Error('网络请求失败，请检查网络连接'));
        }
      });
    });
  }

  // 处理令牌刷新
  handleTokenRefresh(response) {
    try {
      const newToken = response.header['S-Access-Token'] || response.header['s-access-token'];
      if (newToken && newToken !== this.accessToken) {
        console.log('令牌已更新');
        this.accessToken = newToken;
        wx.setStorageSync(this.config.auth.storageKeys.accessToken, newToken);
      }
    } catch (error) {
      console.error('处理令牌刷新失败:', error);
    }
  }

  // 保存图片到相册
  async saveImageToAlbum(arrayBuffer, filename = null) {
    try {
      // 将arrayBuffer转换为base64
      const base64 = wx.arrayBufferToBase64(arrayBuffer);
      const base64Data = 'data:image/png;base64,' + base64;
      
      // 保存到临时文件
      const tempFilePath = await new Promise((resolve, reject) => {
        wx.getFileSystemManager().writeFile({
          filePath: wx.env.USER_DATA_PATH + '/' + (filename || Date.now() + '.png'),
          data: arrayBuffer,
          success: (res) => {
            resolve(wx.env.USER_DATA_PATH + '/' + (filename || Date.now() + '.png'));
          },
          fail: reject
        });
      });

      // 保存到相册
      await new Promise((resolve, reject) => {
        wx.saveImageToPhotosAlbum({
          filePath: tempFilePath,
          success: resolve,
          fail: reject
        });
      });

      return { success: true, path: tempFilePath };
    } catch (error) {
      console.error('保存图片失败:', error);
      throw error;
    }
  }

  // 保存压缩包（批量生成结果）
  async saveBatchResult(arrayBuffer, filename = null) {
    try {
      const fileName = filename || `qr_batch_${Date.now()}.zip`;
      const filePath = wx.env.USER_DATA_PATH + '/' + fileName;
      
      await new Promise((resolve, reject) => {
        wx.getFileSystemManager().writeFile({
          filePath: filePath,
          data: arrayBuffer,
          success: resolve,
          fail: reject
        });
      });

      return { 
        success: true, 
        path: filePath,
        fileName: fileName
      };
    } catch (error) {
      console.error('保存批量结果失败:', error);
      throw error;
    }
  }
}

// 创建单例实例
const apiService = new ApiService();

module.exports = apiService; 